
#include "mycanvas.h"

IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)

BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
    EVT_LEFT_DOWN(             MyCanvas::OnMouseLeftDown)
END_EVENT_TABLE()

MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
                    const wxPoint &pos, const wxSize &size )
    : wxScrolledWindow( parent, id, pos, size, wxHSCROLL | wxVSCROLL | wxBORDER_SUNKEN , _T("Message Flows") )
{
    SetBackgroundColour( wxT("WHITE") );
    SetCursor( wxCursor( wxCURSOR_IBEAM ) );
}

void MyCanvas::OnMouseLeftDown( wxMouseEvent &event )
{
    if(!m_msgtext)
        return;

    wxPoint pt(event.GetPosition());
    int x,y;
    CalcUnscrolledPosition( pt.x, pt.y, &x, &y );

    wxPoint pt1(x,y);

    wxRect xRect;
    wxList::Node *node = m_msglist.GetFirst();
    while (node)
    {
        MsgInfo *xMi = (MsgInfo *)node->GetData();
        if(xMi->pt1.x<xMi->pt2.x)
            xRect = wxRect (xMi->pt1.x,xMi->pt1.y,COLUMN_INTERVAL_LEN,ROW_INTERVAL_LEN);
        else
            xRect = wxRect (xMi->pt2.x,xMi->pt1.y,COLUMN_INTERVAL_LEN,ROW_INTERVAL_LEN);

        if(xRect.Inside(pt1))
        {
            m_msgtext->ShowPosition(xMi->beginpos);
            m_msgtext->SetSelection(xMi->beginpos,xMi->endpos);
            m_msgtext->SetFocus();

            return;
        }
        node = node->GetNext();
    }
}

void MyCanvas::OnDraw(wxDC& dc)
{
    /*draw UE <-> PROXY graph*/
    wxString sTxt[] =
    {
        wxT("UE"),
        wxT("Proxy")
    };

    size_t count=WXSIZEOF(sTxt);

    wxPoint beginPos(60,10);
    m_currentpos = wxPoint(beginPos.x+TEXT_X_OFFSET,beginPos.y+TEXT_Y_OFFSET+ROW_INTERVAL_LEN);

    dc.SetPen(wxPen(*wxBLUE, 1, wxSOLID));
    dc.SetTextForeground(*wxBLUE);
    dc.SetBackgroundMode(wxTRANSPARENT);
    for(size_t i=0;i<count;i++)
    {
        dc.DrawRectangle(beginPos.x+i*COLUMN_INTERVAL_LEN-TEXT_X_OFFSET, beginPos.y, TEXT_RECT_LEN, TEXT_Y_OFFSET);
        dc.DrawText(sTxt[i], beginPos.x+i*COLUMN_INTERVAL_LEN, beginPos.y+TEXT_Y_OFFSET/4);
    }

    for(size_t j=0;j<count;j++)
    {
        dc.DrawLine(beginPos.x+TEXT_X_OFFSET+j*COLUMN_INTERVAL_LEN,beginPos.y+TEXT_Y_OFFSET,beginPos.x+TEXT_X_OFFSET+j*COLUMN_INTERVAL_LEN,beginPos.y+DISPALY_MSG_LEN);
    }

    wxList::Node *node = m_msglist.GetFirst();
    while (node)
    {
        MsgInfo *xMi = (MsgInfo *)node->GetData();
        DrawAMessage(dc,xMi);
        node = node->GetNext();
    }
}

void MyCanvas::DrawNewMessage( wxDC &dc,wxString sTxt,wxPoint pt1,wxPoint pt2)
{
    /*Draw Message Flow*/
    int nDirection=(pt2.x>pt1.x)?1:-1;

    dc.SetPen(*wxTRANSPARENT_PEN);
    dc.SetBrush(*wxTRANSPARENT_BRUSH);
    if(nDirection>0)
    {
        m_currentpos = wxPoint(pt1.x,pt1.y+ROW_INTERVAL_LEN);
        dc.DrawRectangle(pt1.x, pt1.y, pt2.x-pt1.x, pt2.y-pt1.y);

        dc.SetPen(wxPen(*wxRED, 1, wxSOLID));
        dc.SetTextForeground(*wxRED);

        dc.DrawText(sTxt,(pt1.x+pt2.x)/2-2*TEXT_X_OFFSET,pt1.y+TEXT_Y_OFFSET/2);
        dc.DrawLine(pt1.x,pt1.y+TEXT_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);

        dc.DrawLine(pt2.x-ARROW_X_OFFSET,pt1.y+TEXT_Y_OFFSET-ARROW_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);
        dc.DrawLine(pt2.x-ARROW_X_OFFSET,pt1.y+TEXT_Y_OFFSET+ARROW_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);
    }
    else
    {
        m_currentpos = pt2;

        dc.DrawRectangle(pt2.x, pt1.y, pt1.x-pt2.x, pt2.y-pt1.y);

        dc.SetPen(wxPen(*wxBLACK, 1, wxSOLID));
        dc.SetTextForeground(*wxBLACK);
        dc.DrawText(sTxt,(pt1.x+pt2.x)/2-2*TEXT_X_OFFSET,pt1.y+TEXT_Y_OFFSET/2);
        dc.DrawLine(pt1.x,pt1.y+TEXT_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);

        dc.DrawLine(pt2.x+ARROW_X_OFFSET,pt1.y+TEXT_Y_OFFSET-ARROW_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);
        dc.DrawLine(pt2.x+ARROW_X_OFFSET,pt1.y+TEXT_Y_OFFSET+ARROW_Y_OFFSET,pt2.x,pt1.y+TEXT_Y_OFFSET);
    }

    return;
}

void MyCanvas::DrawAMessage( wxDC &dc,MsgInfo *oMsginfo)
{
    if(NULL == oMsginfo)
        return;

    DrawNewMessage(dc,oMsginfo->sTxt,oMsginfo->pt1,oMsginfo->pt2);
    return;
}
